3  * Copyright 2015-2016 gRPC authors.
 
   5  * Licensed under the Apache License, Version 2.0 (the "License");
 
   6  * you may not use this file except in compliance with the License.
 
   7  * You may obtain a copy of the License at
 
   9  *     http://www.apache.org/licenses/LICENSE-2.0
 
  11  * Unless required by applicable law or agreed to in writing, software
 
  12  * distributed under the License is distributed on an "AS IS" BASIS,
 
  13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  14  * See the License for the specific language governing permissions and
 
  15  * limitations under the License.
 
  19 #include <grpc/support/port_platform.h>
 
  26 #include <grpc/support/alloc.h>
 
  27 #include <grpc/support/string_util.h>
 
  29 #include "src/core/ext/filters/client_channel/parse_address.h"
 
  30 #include "src/core/ext/filters/client_channel/resolver_registry.h"
 
  31 #include "src/core/ext/filters/client_channel/server_address.h"
 
  32 #include "src/core/lib/channel/channel_args.h"
 
  33 #include "src/core/lib/gpr/host_port.h"
 
  34 #include "src/core/lib/gpr/string.h"
 
  35 #include "src/core/lib/iomgr/combiner.h"
 
  36 #include "src/core/lib/iomgr/resolve_address.h"
 
  37 #include "src/core/lib/iomgr/unix_sockets_posix.h"
 
  38 #include "src/core/lib/slice/slice_internal.h"
 
  39 #include "src/core/lib/slice/slice_string_helpers.h"
 
  45 class SockaddrResolver : public Resolver {
 
  47   SockaddrResolver(ServerAddressList addresses, ResolverArgs args);
 
  48   ~SockaddrResolver() override;
 
  50   void StartLocked() override;
 
  52   void ShutdownLocked() override {}
 
  55   ServerAddressList addresses_;
 
  56   const grpc_channel_args* channel_args_ = nullptr;
 
  59 SockaddrResolver::SockaddrResolver(ServerAddressList addresses,
 
  61     : Resolver(args.combiner, std::move(args.result_handler)),
 
  62       addresses_(std::move(addresses)),
 
  63       channel_args_(grpc_channel_args_copy(args.args)) {}
 
  65 SockaddrResolver::~SockaddrResolver() {
 
  66   grpc_channel_args_destroy(channel_args_);
 
  69 void SockaddrResolver::StartLocked() {
 
  71   result.addresses = std::move(addresses_);
 
  72   // TODO(roth): Use std::move() once channel args is converted to C++.
 
  73   result.args = channel_args_;
 
  74   channel_args_ = nullptr;
 
  75   result_handler()->ReturnResult(std::move(result));
 
  82 void DoNothing(void* ignored) {}
 
  84 OrphanablePtr<Resolver> CreateSockaddrResolver(
 
  86     bool parse(const grpc_uri* uri, grpc_resolved_address* dst)) {
 
  87   if (0 != strcmp(args.uri->authority, "")) {
 
  88     gpr_log(GPR_ERROR, "authority-based URIs not supported by the %s scheme",
 
  92   // Construct addresses.
 
  93   grpc_slice path_slice =
 
  94       grpc_slice_new(args.uri->path, strlen(args.uri->path), DoNothing);
 
  95   grpc_slice_buffer path_parts;
 
  96   grpc_slice_buffer_init(&path_parts);
 
  97   grpc_slice_split(path_slice, ",", &path_parts);
 
  98   ServerAddressList addresses;
 
  99   bool errors_found = false;
 
 100   for (size_t i = 0; i < path_parts.count; i++) {
 
 101     grpc_uri ith_uri = *args.uri;
 
 102     UniquePtr<char> part_str(grpc_slice_to_c_string(path_parts.slices[i]));
 
 103     ith_uri.path = part_str.get();
 
 104     grpc_resolved_address addr;
 
 105     if (!parse(&ith_uri, &addr)) {
 
 109     addresses.emplace_back(addr, nullptr /* args */);
 
 111   grpc_slice_buffer_destroy_internal(&path_parts);
 
 112   grpc_slice_unref_internal(path_slice);
 
 114     return OrphanablePtr<Resolver>(nullptr);
 
 116   // Instantiate resolver.
 
 117   return OrphanablePtr<Resolver>(
 
 118       New<SockaddrResolver>(std::move(addresses), std::move(args)));
 
 121 class IPv4ResolverFactory : public ResolverFactory {
 
 123   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
 
 124     return CreateSockaddrResolver(std::move(args), grpc_parse_ipv4);
 
 127   const char* scheme() const override { return "ipv4"; }
 
 130 class IPv6ResolverFactory : public ResolverFactory {
 
 132   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
 
 133     return CreateSockaddrResolver(std::move(args), grpc_parse_ipv6);
 
 136   const char* scheme() const override { return "ipv6"; }
 
 139 #ifdef GRPC_HAVE_UNIX_SOCKET
 
 140 class UnixResolverFactory : public ResolverFactory {
 
 142   OrphanablePtr<Resolver> CreateResolver(ResolverArgs args) const override {
 
 143     return CreateSockaddrResolver(std::move(args), grpc_parse_unix);
 
 146   UniquePtr<char> GetDefaultAuthority(grpc_uri* uri) const override {
 
 147     return UniquePtr<char>(gpr_strdup("localhost"));
 
 150   const char* scheme() const override { return "unix"; }
 
 152 #endif  // GRPC_HAVE_UNIX_SOCKET
 
 156 }  // namespace grpc_core
 
 158 void grpc_resolver_sockaddr_init() {
 
 159   grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
 
 160       grpc_core::UniquePtr<grpc_core::ResolverFactory>(
 
 161           grpc_core::New<grpc_core::IPv4ResolverFactory>()));
 
 162   grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
 
 163       grpc_core::UniquePtr<grpc_core::ResolverFactory>(
 
 164           grpc_core::New<grpc_core::IPv6ResolverFactory>()));
 
 165 #ifdef GRPC_HAVE_UNIX_SOCKET
 
 166   grpc_core::ResolverRegistry::Builder::RegisterResolverFactory(
 
 167       grpc_core::UniquePtr<grpc_core::ResolverFactory>(
 
 168           grpc_core::New<grpc_core::UnixResolverFactory>()));
 
 172 void grpc_resolver_sockaddr_shutdown() {}